#include <UnitTest++.h>
#include "../getvoltages.h"
#include "../job.h"
#include <iostream>
#include <string>
#include "../option.h"
#include "../MyMap.h"
#include "fixturesInputOutput.h"

using namespace std;

// Fixtures declared in "fixturesInputOutput.h"

TEST(OutputJobClassPassAlways)
{
    CHECK(true);
}

TEST_FIXTURE(OutputFixture, oneSampleImmediate)
{
	// As verified on oscilloscope!
	persistJobHolder persistJobs;
//	cout << opt.toString() << endl;
	{
//		OutputJob* jobptr = new OutputJob("Output one sample immediate", persistJobs, opt);
		OutputJob* jobptr = CreateOutputJob(persistJobs, opt);
		jobptr->startTask(jobptr->getTaskHandle());						
		jobptr->continueTask(-1.2);
		delete jobptr;
	}
}

TEST_FIXTURE(OutputFixture, twoSamplesImmediate)
{
	// As verified on oscilloscope!
	persistJobHolder persistJobs;
	opt.L["numchannels"]=2;			//for two channels
	opt.S["channels"] += ", dev1/ao1";
	opt.DArray["waveform"][0] = -1.0;
	opt.DArray["waveform"][1] = 2.0;
//	cout << opt.toString() << endl;
	{
		OutputJob* jobptr = CreateOutputJob(persistJobs, opt);
		OutputWaveformDispatch(jobptr, persistJobs, opt);
	}
}
TEST_FIXTURE(IOFixture, sinewaveOutputWaveform)
{
	CHECK_EQUAL(100, numPts);
	Out.opt.L["samples"] = 100;
	Out.opt.D["numperiods"] = 3.0;
	Out.opt.D["frequency"] = 1000.0;
	Out.opt.createarray("waveform", numPts);
	for(int i = 0; i < 100; i++)
		Out.opt.DArray["waveform"][i] = pSineData[i];
//	cout << Out.opt.toString() << endl;	
	
	{	// CreateJob in block to check that job is changed to persistent Job
	OutputJob* jobptr = CreateOutputJob(persistJobs, Out.opt);   // const references ?
	CHECK(jobptr != 0);
	CHECK(jobptr->getTaskHandle() !=0);
	Job& pj = persistJobs.changeToPersist(*jobptr, 0);		// stop when task is done
	pj.startTask(pj.getTaskHandle());
	}
	
	map<TaskHandle,JobState> JL = persistJobs.getJobList();
	typedef map<TaskHandle, JobState>::iterator jobList_iter;
	bool32 taskIsDone = false;
//{	here are some possible values to print
//~	char chanName[100];	
	//~ for(jobList_iter iJL = JL.begin(); iJL != JL.end(); iJL++) {
		//~ cout << "TaskHandle = " << iJL->first << endl;
		//~ cout << "from job pointer get channels = " <<  iJL->second.pJob->getoptS("channels") << endl;
		//~ DAQmxGetTaskName( iJL->first, chanName,100);
		//~ DAQmxGetTaskComplete(iJL->first, &taskIsDone);
		//~ cout << "Task Name is: " << chanName << " -- status: "<< taskIsDone<<endl;
	//~ }
	
	//~ char sysTasks[1000];
	//~ DAQmxGetSysTasks(sysTasks,1000);
	//~ cout << "system tasks: " << sysTasks <<endl;
//}	
	jobList_iter iJL = JL.begin();		// assume one for now
	DAQmxGetTaskComplete(iJL->first, &taskIsDone);
	while(!taskIsDone)
		DAQmxGetTaskComplete(iJL->first, &taskIsDone);

}

TEST_FIXTURE(IOFixture, sinewaveOutputWaveformContinuous)
{
	CHECK_EQUAL(100, numPts);
	Out.opt.L["samples"] = 100;
	Out.opt.D["numperiods"] = 3.0;
	Out.opt.D["frequency"] = 5000.0;
	Out.opt.L["samplemode"] = DAQmx_Val_ContSamps;
	Out.opt.createarray("waveform", numPts);
	for(int i = 0; i < 100; i++)
		Out.opt.DArray["waveform"][i] = pSineData[i];
//	cout << Out.opt.toString() << endl;	
	TaskHandle th = 0;			// task handle for persistent job
	{	// CreateJob in block to check that job is changed to persistent Job
		OutputJob* jobptr = CreateOutputJob(persistJobs, Out.opt);   // const references ?
		CHECK(jobptr != 0);
		th = jobptr->getTaskHandle();
		CHECK(th !=0);
		Job& pj = persistJobs.changeToPersist(*jobptr, 0);		// sameTaskHandle
		pj.startTask(pj.getTaskHandle());
	}
	
	map<TaskHandle,JobState> JL = persistJobs.getJobList();
	typedef map<TaskHandle, JobState>::iterator jobList_iter;
	jobList_iter iJL = JL.begin();
	CHECK(iJL != JL.end());
	CHECK_EQUAL(th, iJL->first);
	
	//~ for(jobList_iter iJL = JL.begin(); iJL != JL.end(); iJL++) 
		//~ cout << "TaskHandle = " << iJL->first << endl;

	persistJobs.clearJob(iJL->first);
	JL = persistJobs.getJobList();		// updated jobs list
	iJL = JL.begin();
	CHECK(iJL == JL.end());

}

